#pragma once 

#include <iostream>
#include<string>
#include<set>
#include<cstdio>
#include"Log.hpp"
const std::string sep = " ";
class Command
{
    private:
        std::set<std::string> _safe_cmd;
        std::string _cond_path;
    private:
        //加载到内存中
        void LoadConf(const std::string &conf)
        {
            std::ifstream in(conf);
            if(!in.is_open())
            {
                LOG(FATAL, "open %s error\n", conf.c_str());
                return;
            }
            std::string line;
            while(std::getline(in, line))
            {
                LOG(INFO,"load command [%s] success!", line.c_str());
                _safe_cmd.insert(line);
            }
            in.close();
        }
    public:
        Command(const std::string& cond_path)
        :_cond_path(cond_path)
        {
            LoadConf(_cond_path);
        }
        std::string PrefixCommand(const std::string & cmd)
        {
            if(cmd.empty()) return std::string();
            auto pos = cmd.find(sep);
            if(pos == std::string::npos) return cmd;
            else return cmd.substr(0,pos);
        }
        bool SafeCheck(const std::string &cmd)
        {
            std::string prefix = PrefixCommand(cmd);
            auto pos = _safe_cmd.find(prefix);
            if(pos == _safe_cmd.end())
                return false;
            return true;
        }
        std::string Excute(const std::string &cmd)
        {
            //1. fork && pipe
            //2. exec
            //2.1 dup
            std::string result;
            if(SafeCheck(cmd))
            {
                //FILE *popen(const char *command, const char *type);
                //popen函数执行shell命令，并创建一个管道来读取命令的输出，"r"表示以读模式打开管道，即获取命令的标准输出
                FILE* fp = popen(cmd.c_str(),"r");
                if(fp == nullptr)
                {
                    return "failed";
                }
                char buffer[1024];
                //char *fgets(char *str, int size, FILE *stream); 
                //behavior:从stream读取字符串直到"\n"，读到sizeof()-1时，保留一个位置给'\0',
                while(fgets(buffer,sizeof(buffer),fp) != NULL)
                {
                    result += buffer;
                } 
                pclose(fp);
            }
            else 
            {
                return "坏人\n";
            }
            return result;

        }
        ~Command()
        {

        }
};